package cloud.shyidong.core.util;

import cloud.shyidong.core.exception.WeixinException;
import com.alibaba.fastjson.JSONObject;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Map;

/**
 * @Description TODO
 * @Author syd
 * @Date 2023/5/9
 */
@Slf4j
public class WeixinUtils {
    
    /**
     * 验签
     *
     * @param verifier
     * @param body
     * @param httpServletRequest
     */
    public static void verifySignature(Verifier verifier, String body, HttpServletRequest httpServletRequest) {
        String nonce = httpServletRequest.getHeader("wechatpay-nonce");
        String signature = httpServletRequest.getHeader("wechatpay-signature");
        String serial = httpServletRequest.getHeader("wechatpay-serial");
        String timestamp = httpServletRequest.getHeader("wechatpay-timestamp");
        log.info("nonce >>> {}", nonce);
        log.info("signature >>> {}", signature);
        log.info("serial >>> {}", serial);
        log.info("timestamp >>> {}", timestamp);
        StringBuilder message = new StringBuilder();
        message.append(timestamp);
        message.append("\n");
        message.append(nonce);
        message.append("\n");
        message.append(body);
        message.append("\n");
        if (!verifier.verify(serial, message.toString().getBytes(StandardCharsets.UTF_8), signature)) {
            throw WeixinException.from("FAIL", "验签失败");
        }
        log.info("验签成功");
    }
    
    public static String decryptBody(String apiV3Key, String body) throws GeneralSecurityException {
        Map<String, Object> map = JSONObject.parseObject(body, Map.class);
        Map<String, String> resourceMap = (Map<String, String>) map.get("resource");
        String ciphertext = resourceMap.get("ciphertext");
        String associated_data = resourceMap.get("associated_data");
        String nonce = resourceMap.get("nonce");
        log.info("密文 >>> {}", ciphertext);
        AesUtil aesUtil = new AesUtil(apiV3Key.getBytes(StandardCharsets.UTF_8));
        String plainText = aesUtil.decryptToString(associated_data.getBytes(StandardCharsets.UTF_8), nonce.getBytes(StandardCharsets.UTF_8), ciphertext);
        log.info("明文 >>> {}", plainText);
        return plainText;
    }
    
}
